package beanstao.util.store.dal;

import java.util.HashMap;

import beanstao.util.Sber;
import beanstao.util.interfaces.IManager;
import beanstao.util.module.AbstractManager;
import beanstao.util.reflect.Mirror;
import beanstao.util.store.database.DbHelper;
import beanstao.util.store.database.DbSetting;
import beanstao.util.store.database.Fields;
import beanstao.util.store.domainobject.DomainSetting;
import beanstao.util.xml.XDocument;


@SuppressWarnings("unchecked")
public abstract class DalManager extends AbstractManager implements IManager
{
	private static final Object initLock = new Object();

	protected abstract String getDalPackage();

	/**
	 * 获得DAL的Class
	 * 
	 * @param clsName
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	protected Class getDalClass(String clsSimpleName)
	{
		Sber sber = Sber.ME(this.getDalPackage());
		if (!".".equals(sber.end()))
			sber.append(".");
		sber.append(clsSimpleName);
		Class klass = null;
		try
		{
			klass = Class.forName(sber.toString());
		}
		catch (ClassNotFoundException e1)
		{
			this.logWarn(sber.toString() + " 类未找到。");
		}
		return klass;
	}

	private Object _dbStore;

	private Object _xmlStore;

	private DomainSetting _domainSetting;

	@Override
	public boolean initializes(Object... objects)
	{
		try
		{

			for (Object object : objects)
				if (object instanceof DbSetting)
					_dbStore = object;
				else if (object instanceof XDocument)
					_xmlStore = object;
				else if (object instanceof DomainSetting)
					_domainSetting = (DomainSetting) object;
				else
					this.logWarn(String.format("类型(%s)初始化时参数类型未知或不可用。参数个数:%s个。", object.getClass().getSimpleName(), objects.length));
			return true;
		}
		catch (Exception e)
		{
			return false;
		}
	}

	@Override
	public boolean reStart()
	{
		boolean isStart = false;
		if (this.stop())
			isStart = this.start();
		return isStart;
	}

	@Override
	public boolean start()
	{
		return true;
	}

	@Override
	public boolean stop()
	{
		try
		{
			_dalMap.clear();
		}
		catch (Exception e)
		{
			this.logWarn("停止服务发生异常。", e);
			return false;
		}
		return true;
	}

	// ======================

	@SuppressWarnings("rawtypes")
	private static final HashMap<String, Dal> _dalMap = new HashMap<String, Dal>();

	/**
	 * @param dalName
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Dal createDal(String dalName)
	{
		Dal dal = null;
		if (!_dalMap.containsKey(dalName))
		{
			Class klass = this.getDalClass(dalName);
			Mirror<Dal> mirror = Mirror.me(klass);
			try
			{
				// 根据DAL的类名去掉最后的“DAL”字符得到该实体
				String dalKey = dalName.substring(0, dalName.length() - 3);

				Object store = null; // DalManager的初始化时传入的第一个参数；

				// 根据将要实例的类型判断如何实例化，现在一般是两种，一种是数据库，一种是XML文件
				if (mirror.isOf(DbDal.class))
					store = DbHelper.ME((DbSetting) _dbStore);
				else if (mirror.isOf(XmlDal.class))
					store = _xmlStore;
				// 创建DalManager的实例
				Fields fieldList = _domainSetting.getFields(dalKey);

				dal = mirror.born(store, fieldList);
			}
			catch (Exception e)
			{
				this.logWarn(dalName + " 初始化发生异常。" + e.getMessage(), e);
			}
			synchronized (initLock)
			{
				_dalMap.put(dalName, dal);
			}
			return dal;
		}
		else
			return _dalMap.get(dalName);
	}

}
